home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Graphics / sKulpt / skulpt-src / D3d-Enum.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-18  |  13.1 KB  |  377 lines

  1. //-----------------------------------------------------------------------------
  2. // File: D3DEnum.cpp
  3. //
  4. // Desc: Functions to enumerate DDraw/D3D drivers, devices, and modes.
  5. //
  6. // Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include <windowsx.h>
  10. #include <stdio.h>
  11.  
  12. // Includes D3D
  13. #define  D3D_OVERLOADS
  14. #include <ddraw.h>
  15. #include <d3d.h>
  16. #include <d3dx.h>
  17.  
  18. // Includes utilitaires D3D
  19. #include "D3DEnum.h"
  20. #include "d3dmath.h"
  21. #include "d3dutil.h"
  22.  
  23. // Ids Resources
  24. #include "resource.h"
  25.  
  26. // Constantes
  27. #include "const.h"
  28.  
  29. // Types
  30. #include "types.h"
  31.  
  32. // Variables globales projet
  33. #include "vars.h"
  34.  
  35. // Prototypes fonctions autres modules
  36. #include "proto.h"
  37.  
  38. // Macros
  39. #include "macros.h"
  40.  
  41. //-----------------------------------------------------------------------------
  42. // Global data for the enumerator functions
  43. //-----------------------------------------------------------------------------
  44. #ifndef NO3D
  45. static HRESULT (*g_fnAppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) = NULL;
  46.  
  47. static D3DEnum_DeviceInfo g_pDeviceList[20];
  48. static DWORD g_dwNumDevicesEnumerated = 0L;
  49. static DWORD g_dwNumDevices           = 0L;
  50. //-----------------------------------------------------------------------------
  51. // Name: DeviceEnumCallback()
  52. // Desc: Callback function for enumerating devices
  53. //-----------------------------------------------------------------------------
  54. static HRESULT WINAPI DeviceEnumCallback( TCHAR* strDesc, TCHAR* strName,
  55.                                           D3DDEVICEDESC7* pDesc,
  56.                                           VOID* pParentInfo )
  57. {
  58.     vTrace("       --> Device n° %d : %s (%s)", ++g_dwNumDevicesEnumerated, strName, strDesc);
  59.  
  60.     D3DEnum_DeviceInfo* pDriverInfo = (D3DEnum_DeviceInfo*)pParentInfo;
  61.     D3DEnum_DeviceInfo* pDeviceInfo = &g_pDeviceList[g_dwNumDevices];
  62.     ZeroMemory( pDeviceInfo, sizeof(D3DEnum_DeviceInfo) );
  63.  
  64.     // Select either the HAL or HEL device desc:
  65.     pDeviceInfo->bHardware = pDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION;
  66.     memcpy( &pDeviceInfo->ddDeviceDesc, pDesc, sizeof(D3DDEVICEDESC7) );
  67.  
  68.     // Bail if the device has no windowed support
  69.     if(!pDriverInfo->bDesktopCompatible)
  70.         return D3DENUMRET_OK;
  71.  
  72.     pDeviceInfo->bDesktopCompatible = TRUE;
  73.  
  74.     // Set up device info for this device
  75.     pDeviceInfo->ddDriverCaps       = pDriverInfo->ddDriverCaps;
  76.     pDeviceInfo->ddHELCaps          = pDriverInfo->ddHELCaps;
  77.     pDeviceInfo->guidDevice         = pDesc->deviceGUID;
  78.     pDeviceInfo->pDeviceGUID        = &pDeviceInfo->guidDevice;
  79.  
  80.     // Copy the driver GUID and description for the device
  81.     if( pDriverInfo->pDriverGUID )
  82.     {
  83.         pDeviceInfo->guidDriver  = pDriverInfo->guidDriver;
  84.         pDeviceInfo->pDriverGUID = &pDeviceInfo->guidDriver;
  85.         lstrcpyn( pDeviceInfo->strDesc, pDriverInfo->strDesc, 39 );
  86.     }
  87.     else
  88.     {
  89.         pDeviceInfo->pDriverGUID = NULL;
  90.         lstrcpyn( pDeviceInfo->strDesc, strName, 39 );
  91.     }
  92.  
  93.     // Avoid duplicates: only enum HW devices for secondary DDraw drivers.
  94.     if( NULL != pDeviceInfo->pDriverGUID && FALSE == pDeviceInfo->bHardware )
  95.             return D3DENUMRET_OK;
  96.  
  97.     // Give the app a chance to accept or reject this device.
  98.     if( g_fnAppConfirmFn )
  99.         if( FAILED( g_fnAppConfirmFn( &pDeviceInfo->ddDriverCaps,
  100.                                       &pDeviceInfo->ddDeviceDesc ) ) )
  101.             return D3DENUMRET_OK;
  102.  
  103.  
  104.     // Accept the device and return
  105.     g_dwNumDevices++;
  106.  
  107.     return D3DENUMRET_OK;
  108. }
  109.  
  110. //-----------------------------------------------------------------------------
  111. // Name: DriverEnumCallback()
  112. // Desc: Callback function for enumerating drivers.
  113. //-----------------------------------------------------------------------------
  114. static BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,
  115.                                        TCHAR* strName, VOID*, HMONITOR )
  116. {
  117.     D3DEnum_DeviceInfo d3dDeviceInfo;
  118.  
  119.     vTrace("    * Driver %s (%s)", strName, strDesc);
  120.     
  121.     // Copy data to a device info structure
  122.     ZeroMemory( &d3dDeviceInfo, sizeof(d3dDeviceInfo) );
  123.     lstrcpyn( d3dDeviceInfo.strDesc, strDesc, 39 );
  124.     d3dDeviceInfo.ddDriverCaps.dwSize = sizeof(DDCAPS);
  125.     d3dDeviceInfo.ddHELCaps.dwSize    = sizeof(DDCAPS);
  126.     lpDD->GetCaps( &d3dDeviceInfo.ddDriverCaps, &d3dDeviceInfo.ddHELCaps );
  127.     if( pGUID )
  128.     {
  129.         d3dDeviceInfo.guidDriver = (*pGUID);
  130.         d3dDeviceInfo.pDriverGUID = &d3dDeviceInfo.guidDriver;
  131.     }
  132.  
  133.     // Record whether the device can render into a desktop window
  134.     if( d3dDeviceInfo.ddDriverCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED )
  135.         if( NULL == d3dDeviceInfo.pDriverGUID )
  136.             d3dDeviceInfo.bDesktopCompatible = TRUE;
  137.  
  138.     // Now, enumerate all the 3D devices
  139.     lpD3D->EnumDevices( DeviceEnumCallback, &d3dDeviceInfo );
  140.  
  141.     return DDENUMRET_OK;
  142. }
  143.  
  144. #endif
  145.  
  146. //-----------------------------------------------------------------------------
  147. // Name: D3DEnum_EnumerateDevices()
  148. // Desc: Enumerates all drivers, devices, and modes. The callback function is
  149. //       called each device, to confirm that the device supports the feature
  150. //       set required by the app.
  151. //-----------------------------------------------------------------------------
  152. HRESULT D3DEnum_EnumerateDevices( HRESULT (*AppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) )
  153. {
  154. #ifndef NO3D
  155.     // Store the device enumeration callback function
  156.     g_fnAppConfirmFn = AppConfirmFn;
  157.  
  158.     // Enumerate drivers, devices, and modes
  159.     DirectDrawEnumerateEx( DriverEnumCallback, NULL, 
  160.                            DDENUM_ATTACHEDSECONDARYDEVICES |
  161.                            DDENUM_DETACHEDSECONDARYDEVICES |
  162.                            DDENUM_NONDISPLAYDEVICES );
  163.  
  164.     // Make sure devices were actually enumerated
  165.     if( 0 == g_dwNumDevicesEnumerated )
  166.     {
  167.         vTrace("*** E0005 : Aucun device D3D énuméré");
  168.         return D3DENUMERR_ENUMERATIONFAILED;
  169.     }
  170.     if( 0 == g_dwNumDevices )
  171.     {
  172.         vTrace("*** E0006 : Aucun device D3D accepté");
  173.         return D3DENUMERR_SUGGESTREFRAST;
  174.     }
  175. #endif
  176.     return S_OK;
  177. }
  178.  
  179. //-----------------------------------------------------------------------------
  180. // Name: D3DEnum_GetDevices()
  181. // Desc: Returns a ptr to the array of D3DEnum_DeviceInfo structures.
  182. //-----------------------------------------------------------------------------
  183. VOID D3DEnum_GetDevices( D3DEnum_DeviceInfo** ppDevices, DWORD* pdwCount )
  184. {
  185. #ifndef NO3D
  186.     if( ppDevices )
  187.         (*ppDevices) = g_pDeviceList;
  188.     if( pdwCount )
  189.         (*pdwCount)  = g_dwNumDevices;
  190. #endif
  191. }
  192.  
  193. //-----------------------------------------------------------------------------
  194. // Name: UpdateDialogControls()
  195. // Desc: Builds the list of devices and modes for the combo boxes in the device
  196. //       select dialog box.
  197. //-----------------------------------------------------------------------------
  198. static VOID UpdateDialogControls( HWND hDlg, D3DEnum_DeviceInfo* pCurrentDevice)
  199. {
  200. #ifndef NO3D
  201.     // Get access to the enumerated device list
  202.     D3DEnum_DeviceInfo* pDeviceList;
  203.     DWORD               dwNumDevices;
  204.     D3DEnum_GetDevices( &pDeviceList, &dwNumDevices );
  205.  
  206.     // Access to UI controls
  207.     HWND hwndDevice         = GetDlgItem( hDlg, IDC_DEVICE_COMBO );
  208.  
  209.     // Reset the content in each of the combo boxes
  210.     ComboBox_ResetContent( hwndDevice );
  211.  
  212.     // Add a list of devices to the device combo box
  213.     for( DWORD device = 0; device < dwNumDevices; device++ )
  214.     {
  215.         D3DEnum_DeviceInfo* pDevice = &pDeviceList[device];
  216.  
  217.         // Add device name to the combo box
  218.         DWORD dwItem = ComboBox_AddString( hwndDevice, pDevice->strDesc );
  219.         
  220.         // Set the remaining UI states for the current device
  221.         if( pDevice == pCurrentDevice )
  222.             // Set the combobox selection on the current device
  223.             ComboBox_SetCurSel( hwndDevice, dwItem );
  224.     }
  225. #endif
  226. }
  227.  
  228. //-----------------------------------------------------------------------------
  229. // Name: ChangeDeviceProc()
  230. // Desc: Windows message handling function for the device select dialog
  231. //-----------------------------------------------------------------------------
  232. #ifndef NO3D
  233. static BOOL CALLBACK ChangeDeviceProc( HWND hDlg, UINT uiMsg, WPARAM wParam, 
  234.                                        LPARAM lParam )
  235. {
  236.     static D3DEnum_DeviceInfo** ppDeviceArg;
  237.     static D3DEnum_DeviceInfo* pCurrentDevice;
  238.  
  239.     // Get access to the enumerated device list
  240.     D3DEnum_DeviceInfo* pDeviceList;
  241.     DWORD               dwNumDevices;
  242.     D3DEnum_GetDevices( &pDeviceList, &dwNumDevices );
  243.  
  244.     // Handle the initialization message
  245.     if( WM_INITDIALOG == uiMsg )
  246.     {
  247.         // Get the app's current device, passed in as an lParam argument        
  248.         ppDeviceArg = (D3DEnum_DeviceInfo**)lParam;
  249.         if( NULL == ppDeviceArg )
  250.             return FALSE;
  251.  
  252.         // Setup temp storage pointers for dialog
  253.         pCurrentDevice = (*ppDeviceArg);
  254.  
  255.         UpdateDialogControls( hDlg, pCurrentDevice);
  256.  
  257.         return TRUE;
  258.     }
  259.     else if( WM_COMMAND == uiMsg )
  260.     {
  261.         HWND hwndDevice   = GetDlgItem( hDlg, IDC_DEVICE_COMBO );
  262.  
  263.         // Get current UI state
  264.         DWORD dwDevice   = ComboBox_GetCurSel( hwndDevice );
  265.  
  266.         D3DEnum_DeviceInfo* pDevice = &pDeviceList[dwDevice];
  267.         
  268.         if( IDOK == LOWORD(wParam) )
  269.         {
  270.             // Handle the case when the user hits the OK button. Check if any
  271.             // of the options were changed
  272.             if( pDevice != pCurrentDevice)
  273.             {
  274.                 // Return the newly selected device and its new properties
  275.                 (*ppDeviceArg)              = pDevice;
  276.                 EndDialog( hDlg, IDOK );
  277.             }
  278.             else
  279.                 EndDialog( hDlg, IDCANCEL );
  280.  
  281.             return TRUE;
  282.         }
  283.         else if( IDCANCEL == LOWORD(wParam) )
  284.         {
  285.             // Handle the case when the user hits the Cancel button
  286.             EndDialog( hDlg, IDCANCEL );
  287.             return TRUE;
  288.         }
  289.  
  290.         // Keep the UI current
  291.         UpdateDialogControls( hDlg, &pDeviceList[dwDevice]);
  292.         return TRUE;
  293.     }
  294.  
  295.     return FALSE;
  296. }
  297. #endif
  298.  
  299. //-----------------------------------------------------------------------------
  300. // Name: D3DEnum_UserChangeDevice()
  301. // Desc: Pops up a dialog which allows the user to select a new device.
  302. //-----------------------------------------------------------------------------
  303. HRESULT D3DEnum_UserChangeDevice( D3DEnum_DeviceInfo** ppDevice )
  304. {
  305. #ifndef NO3D
  306.     if( IDOK == DialogBoxParam( hInst,
  307.                                 MAKEINTRESOURCE(IDD_CHANGEDEVICE),
  308.                                 GetForegroundWindow(),
  309.                                 ChangeDeviceProc, (LPARAM)ppDevice ) )
  310.         return S_OK;
  311.  
  312.     return E_FAIL;
  313. #else
  314.         return S_OK;
  315. #endif
  316. }
  317.  
  318. //-----------------------------------------------------------------------------
  319. // Name: D3DEnum_SelectDefaultDevice()
  320. // Desc: Pick a default device, preferably hardware and desktop compatible.
  321. //-----------------------------------------------------------------------------
  322. HRESULT D3DEnum_SelectDefaultDevice( D3DEnum_DeviceInfo** ppDevice,
  323.                                      DWORD dwFlags )
  324. {
  325. #ifndef NO3D
  326.     // Check arguments
  327.     if( NULL == ppDevice )
  328.         return E_INVALIDARG;
  329.  
  330.     // Get access to the enumerated device list
  331.     D3DEnum_DeviceInfo* pDeviceList;
  332.     DWORD               dwNumDevices;
  333.     D3DEnum_GetDevices( &pDeviceList, &dwNumDevices );
  334.  
  335.     // Look for windowable software, hardware, and hardware TnL devices
  336.     D3DEnum_DeviceInfo* pRefRastDevice     = NULL;
  337.     D3DEnum_DeviceInfo* pSoftwareDevice    = NULL;
  338.     D3DEnum_DeviceInfo* pHardwareDevice    = NULL;
  339.     D3DEnum_DeviceInfo* pHardwareTnLDevice = NULL;
  340.  
  341.     for( DWORD i=0; i<dwNumDevices; i++ )
  342.     {
  343.         if( pDeviceList[i].bDesktopCompatible )
  344.         {
  345.             if( pDeviceList[i].bHardware )
  346.             {
  347.                 if( (*pDeviceList[i].pDeviceGUID) == IID_IDirect3DTnLHalDevice )
  348.                     pHardwareTnLDevice = &pDeviceList[i];
  349.                 else
  350.                     pHardwareDevice = &pDeviceList[i];
  351.             }
  352.             else
  353.             {
  354.                 if( (*pDeviceList[i].pDeviceGUID) == IID_IDirect3DRefDevice )
  355.                     pRefRastDevice = &pDeviceList[i];
  356.                 else
  357.                     pSoftwareDevice = &pDeviceList[i];
  358.             }
  359.         }
  360.     }
  361.  
  362.     // Prefer a hardware TnL device first, then a non-TnL hardware device, and
  363.     // finally, a software device.
  364.     if( 0 == ( dwFlags & D3DENUM_SOFTWAREONLY ) && pHardwareTnLDevice )
  365.         (*ppDevice) = pHardwareTnLDevice;
  366.     else if( 0 == ( dwFlags & D3DENUM_SOFTWAREONLY ) && pHardwareDevice )
  367.         (*ppDevice) = pHardwareDevice;
  368.     else if( pSoftwareDevice )
  369.         (*ppDevice) = pSoftwareDevice;
  370.     else if( pRefRastDevice )
  371.         (*ppDevice) = pRefRastDevice;
  372.     else
  373.         return D3DENUMERR_NOCOMPATIBLEDEVICES;
  374. #endif
  375.     return S_OK;
  376. }
  377.